#pragma once
#include <iostream>
#include <vector>
#include <cstdlib>
#include <ctime>
#include <fstream>
#include <sys/stat.h>
#include "acl/acl.h"
#include "kernel_operator.h"

#define INFO_LOG(fmt, args...) fprintf(stdout, "[INFO]  " fmt "\n", ##args)
#define WARN_LOG(fmt, args...) fprintf(stdout, "[WARN]  " fmt "\n", ##args)
#define ERROR_LOG(fmt, args...) fprintf(stdout, "[ERROR]  " fmt "\n", ##args)
#ifndef ACL_CHECK
#define ACL_CHECK(x)                                                                                                   \
    if (auto error_ret = (x) != ACL_ERROR_NONE) {                                                                      \
        const char* error_msg = aclGetRecentErrMsg();                                                                  \
        ERROR_LOG("Error message: %s", error_msg ? error_msg : "Unknown error");                                       \
        ERROR_LOG("ACL_CHECK failed: " #x);                                                                            \
        exit(error_ret);                                                                                               \
    } else {                                                                                                           \
        if (0) {                                                                                                       \
            INFO_LOG("ACL_CHECK success: " #x);                                                                        \
        }                                                                                                              \
    }
#endif

#define DEVICE 0
#define BLOCKS 20

/**
 * @brief Read data from file
 * @param [in] filePath: file path
 * @param [out] fileSize: file size
 * @return read result
 */
bool ReadFile(const std::string &filePath, size_t &fileSize, void *buffer, size_t bufferSize)
{
    struct stat sBuf;
    int fileStatus = stat(filePath.data(), &sBuf);
    if (fileStatus == -1) {
        ERROR_LOG("Failed to get file.");
        return false;
    }
    if (S_ISREG(sBuf.st_mode) == 0) {
        ERROR_LOG("%s is not a file, please enter a file", filePath.c_str());
        return false;
    }

    std::ifstream file;
    file.open(filePath, std::ios::binary);
    if (!file.is_open()) {
        ERROR_LOG("Open file failed. path = %s", filePath.c_str());
        return false;
    }

    std::filebuf *buf = file.rdbuf();
    size_t size = buf->pubseekoff(0, std::ios::end, std::ios::in);
    if (size == 0) {
        ERROR_LOG("file size is 0");
        file.close();
        return false;
    }
    if (size > bufferSize) {
        ERROR_LOG("file size is larger than buffer size");
        file.close();
        return false;
    }
    buf->pubseekpos(0, std::ios::in);
    buf->sgetn(static_cast<char *>(buffer), size);
    fileSize = size;
    file.close();
    return true;
}



